package com.tiger.utils;

import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;

import org.apache.commons.lang3.StringUtils;

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.json.PackageVersion;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.module.SimpleModule;

/**
 * RequestBody和ResponseBody的序列化
 * @author andy
 *
 */
public class JsonObjectMapper extends ObjectMapper {
	/**
	 * 
	 */
	private static final long serialVersionUID = -7557974607378726931L;

	public JsonObjectMapper() {
        super();        
        this.registerModule(new BaseJodaModule());
        this.setSerializationInclusion(Include.NON_NULL);
    }  
      
    public class BaseJodaModule extends SimpleModule {
    	/**
		 * 
		 */
		private static final long serialVersionUID = 1235602221843144185L;

		public BaseJodaModule() {
    		super(PackageVersion.VERSION);
    		addSerializer(LocalDate.class, new LocalDateJsonSerializer());
    		addDeserializer(LocalDate.class, new LocalDateJsonDeserializer());
    		addSerializer(LocalTime.class, new LocalTimeJsonSerializer());
    		addDeserializer(LocalTime.class, new LocalTimeJsonDeserializer());
    		addSerializer(LocalDateTime.class, new LocalDateTimeJsonSerializer());
    		addDeserializer(LocalDateTime.class, new LocalDateTimeJsonDeserializer());
    		//setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
    	}
    }
    
    public class LocalDateTimeJsonDeserializer extends com.fasterxml.jackson.databind.JsonDeserializer<LocalDateTime> {

    	private DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    	@Override
    	public LocalDateTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
    		String value = p.readValueAs(String.class);
    		return StringUtils.isEmpty(value) ? null : LocalDateTime.parse(value, formatter);
    	}

    }
    
    public class LocalDateTimeJsonSerializer extends com.fasterxml.jackson.databind.JsonSerializer<LocalDateTime> {
    	
    	private DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    	@Override
    	public void serialize(LocalDateTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException {
    		gen.writeString(formatter.format(value));
    	}
    	
    }

    public class LocalTimeJsonSerializer extends com.fasterxml.jackson.databind.JsonSerializer<LocalTime> {
    	
    	@Override
    	public void serialize(LocalTime value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException {
    		gen.writeString(value.toString());
    	}
    	
    }

    public class LocalDateJsonSerializer extends com.fasterxml.jackson.databind.JsonSerializer<LocalDate> {

    	@Override
    	public void serialize(LocalDate value, JsonGenerator gen, SerializerProvider serializers) throws IOException, JsonProcessingException {
    		gen.writeString(value.toString());
    	}

    }

    public class LocalDateJsonDeserializer extends com.fasterxml.jackson.databind.JsonDeserializer<LocalDate> {
    	
    	@Override
    	public LocalDate deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
    		String value = p.readValueAs(String.class);
    		return StringUtils.isEmpty(value) ? null : LocalDate.parse(value);
    	}
    	
    }
    
    public class LocalTimeJsonDeserializer extends com.fasterxml.jackson.databind.JsonDeserializer<LocalTime> {

    	@Override
    	public LocalTime deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
    		String value = p.readValueAs(String.class);
    		return StringUtils.isEmpty(value) ? null : LocalTime.parse(value);
    	}
    	
    }


}
